/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       army_mover.h

	$Header: /game/army_mover.h $

	$NoKeywords: $

 ************************************************************************/

#ifndef ARMY_MOVER_H_INCLUDED
#define ARMY_MOVER_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "adventure_path.h"
#include "adventure_sounds.h"
#include "army_ptr.h"
#include "idle_processor.h"

class	t_adventure_map_window;
class	t_adventure_path_finder;
struct	t_adventure_path_point;
class	t_army;
class	t_hero;
class	t_window;

struct t_stealth_experience
{
	t_hero* hero;
	int		experience;
};

// ------------------------------------------------------------------------
// class to move army on adventure map
// ------------------------------------------------------------------------
class t_army_mover : public t_idle_processor_no_delay, public t_counted_object
{
public:
	t_army_mover( t_adventure_map_window* window, t_army* army, 
				  bool limit_move = true, t_adventure_path_finder const* path_finder = 0 );
	virtual ~t_army_mover();

	void							cancel_move();
	t_adv_map_point const&			get_actual_destination() const;
	t_army*							get_army() const;
	t_adv_map_point const&			get_original_position() const;
	bool							is_multiple_turn_move() const;
	bool							is_done() const;
	virtual void					on_idle();

protected:
	t_army_mover();

	virtual void	activate_trigger();
	void			do_hidden_move();
	void			do_movement();
	void			end_move();
	void			enter_new_square();
	virtual void	expend_movement( int amount );
	void			finish_path();
	void			initialize( t_adventure_map_window* window, t_army* army, 
								bool limit_move, t_adventure_path_finder const* path_finder,
								bool use_army_path );
	void			mark_eluded_army( t_army const& army );
	virtual void	mark_eluded_armies();
	virtual void	on_end();
	virtual void	on_starting_new_square();
	void			prepare_move( int frame );
	void			report_stealth();
	virtual void	start_new_square();
	virtual void	trigger_event();

	t_adv_map_point			m_actual_destination;
	t_army_ptr              m_army;
	int						m_cell_distance;
	int						m_crossing_point;
	t_screen_point			m_delta;
	int						m_distance;
	int						m_distance_delta;
	int						m_divisor;
	bool					m_exceeded_move_limit;
	int						m_frames;
	bool                    m_halted;
	bool					m_has_trigger;
	bool					m_in_trigger;
	bool					m_is_visible;
	bool					m_landing;
	bool					m_limit_move;
	int						m_movement_expended;
	t_managed_sound_ptr		m_movement_sound;
	t_screen_point			m_offset;
	t_adv_map_point			m_original_position;
	t_adventure_path		m_path;
	t_playing_sound_ptr					m_sound;
	std::vector<t_stealth_experience>	m_stealth_experience;
	int									m_step;
	t_adventure_path_point				m_trigger_point;
	t_adventure_map_window*				m_window;
};

inline t_adv_map_point const& t_army_mover::get_original_position() const
{
	return m_original_position;
}
// ------------------------------------------------------------------------
// class to move army on adventure map
// ------------------------------------------------------------------------
class t_enemy_army_mover : public t_army_mover
{
public:
	t_enemy_army_mover( t_adventure_map_window* window, t_army* army );
	virtual ~t_enemy_army_mover();
protected:
	virtual void expend_movement( int amount );
	virtual void on_end();
};

// ------------------------------------------------------------------------
// class to move army on adventure map
// ------------------------------------------------------------------------
class t_enemy_army_attack : public t_enemy_army_mover
{
public:
	t_enemy_army_attack( t_adventure_map_window* window, t_army* army, t_army* target );
	virtual ~t_enemy_army_attack();
protected:
	virtual void activate_trigger();
	virtual void on_end();

	t_army_ptr	    m_target;
};

#endif // ARMY_MOVER_H_INCLUDED